;
window.requestAnimationFrame = window.requestAnimationFrame || function (a) {
	return setTimeout(a, 1000 / 60)
};
window.cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;

function FragmentBanner(option) {

	//实例化时，可传的参数
	this.whiteList = ['container', 'controller', 'size', 'imgs', 'size', 'grid', 'index', 'fnTime', 'boxTime', 'type'];

	//容器将包容控制器
	this.container = '.banner';

	//默认的控制器
	this.controller = {
		view: '.banner-view',
		btn: '.banner-btn',
		num: '.banner-number',
		progre: '.banner-progres'
	};

	//栅格 行*列
	this.grid = {
		line: 5,
		list: 10
	};

	//容器的大小
	this.size = {
		width: 1200,
		height: 675,
	};

	//切换类型
	this.type = 1;

	//索引位置
	this.index = 0;

	//函数每次切换时间
	this.fnTime = 5000;

	//栅格每次运动时间
	this.boxTime = 2000;

	//栅格运动结束的时间
	this.activeTime = new Date();

	for (var a = 0, attrLenght = this.whiteList.length; a < attrLenght; a++) {

		var attr = this.whiteList[a];
		if (option[attr] != undefined) {

			this[attr] = option[attr];
		}
	}
	for (var i in option) {

		if (this.whiteList[i] !== undefined) {
			;
		}
	}

	this.init();
}

FragmentBanner.prototype = {

	constructor: FragmentBanner,

	init: function () {

		this.container = document.querySelector(this.container)
		if (!this.container) {

			return alert('获取banner容器失败');
		} else {

			this.container.style.width = this.size.width + 'px';
			this.container.style.height = this.size.height + 'px';
		}

		this.elem = {};
		for (var e in this.controller) {

			this.elem[e] = this.container.querySelector(this.controller[e]);
			if (this.elem[e] == null) {

				return alert('获取' + e + '容器');
			}
		}

		//栅格
		var w = this.size.width / this.grid.list,
			h = this.size.height / this.grid.line;

		this.elem.viewBox = new Array();
		for (var i = 0, iL = this.grid.line; i < iL; i++) {

			for (var j = 0, jL = this.grid.list; j < jL; j++) {

				var newI = document.createElement('i');

				this.setCss(newI, {
					width: w + 'px',
					height: h + 'px',
					left: 0,
					top: 0,
					opacity: 1,
					backgroundImage: 'url("' + this.imgs[this.index] + '")',
					backgroundSize: this.size.width + 'px ' + this.size.height + 'px',
					backgroundPosition: w * -j + 'px ' + h * -i + 'px'
				});

				this.elem.view.appendChild(newI);
				this.elem.viewBox.push(newI);
			}
		}

		//按钮动作
		for (var b = 1; b >= 0; b--) {

			var oB = document.createElement('span');
			(b) ? oB.innerHTML = '&lt;': oB.innerHTML = '&gt;';
			oB.setIndex = b;
			oB.onclick = function (obj) {

				this.show({
					switch: true,
					change: obj.setIndex == 0
				});

			}.bind(this, oB);
			this.elem.btn.appendChild(oB);
		}

		//数量
		for (var n = 0, nL = this.imgs.length; n < nL; n++) {

			var oI = document.createElement('i');

			oI.setIndex = n;
			oI.onclick = function (obj) {

				//显示动画
				this.show({
					switch: true,
					change: obj.setIndex
				});
			}.bind(this, oI)
			this.elem.num.appendChild(oI);
		}
		this.elem.numFind = this.elem.num.querySelectorAll('i');

		//进度条
		this.progre = new Array;
		for (var p = 1; p >= 0; p--) {

			var oP = document.createElement('i');
			this.setCss(oP, {
				width: 0,
				backgroundColor: p ? '#00c3ff' : '#ffc300'
			});
			this.elem.progre.appendChild(oP);
			this.progre.push(oP);
		}

		//显示动画
		this.show();

		this.elem.numFind[this.index].className = 'on';
	},

	setIndex: function () {

		this.index %= this.imgs.length;

		this.index = (this.index < 0) ? this.imgs.length - 1 : this.index;

		this.elem.numFind[this.index].className = 'on';
	},

	getTypeTime: function () {

		var timer = new Array();
		switch (this.type) {

			case 1:

				timer.push(this.boxTime / 4 + Math.random() * this.boxTime / 4);
				timer.push(timer[0]);
				break;

			default:

				timer.push([Math.random() * this.boxTime / 5, this.boxTime / 10 * 3]);
				timer.push(timer[0][0] + timer[0][1]);
				break;
		}

		return timer;
	},

	show: function (order) {

		order = order || {};

		if (new Date() >= this.activeTime) {

			this.elem.numFind[this.index].className = '';

			//下次播放动画时候的进度条
			this.setCss(this.progre[1], {
					width: 0
				})
				.anime(this.progre[1], {
					width: this.size.width
				}, this.fnTime, function () {

					this.show({
						switch: true,
						change: true
					});
				}.bind(this));

			var status = true,
				activeTime = 0;

			for (var i = 0, iL = this.elem.viewBox.length; i < iL; i++) {

				var startTime = this.getTypeTime(),
					endTime = this.getTypeTime(),
					obj = this.elem.viewBox[i];

				activeTime = Math.max(activeTime, startTime[1] + endTime[1]);

				this.anime(obj, {
					left: Math.ceil(Math.random() * this.size.width * 2 - this.size.width),
					top: Math.ceil(Math.random() * this.size.height * 2 - this.size.height),
					opacity: 0
				}, startTime[0], function (obj) {

					if (order.switch && status) {

						if (/number/i.test(typeof order.change)) {

							this.index = order.change;
						} else {

							(order.change) ? ++this.index: --this.index;
						}

						this.setIndex();
						this.elem.numFind[this.index].className = 'on';
						status = false;
					}

					this.setCss(obj, {
							backgroundImage: 'url("' + this.imgs[this.index] + '")'
						})
						.anime(obj, {
							left: 0,
							top: 0,
							opacity: 1
						}, endTime[0]);
				}.bind(this, obj));
			}

			//栅格结束运动的时间
			this.activeTime = new Date(new Date().getTime() + activeTime);

			this.setCss(this.progre[0], {
					width: 0
				})
				.anime(this.progre[0], {
					width: this.size.width
				}, activeTime);
		}
	},

	setCss: function (obj, json) {

		for (c in json) {

			if (c == 'opacity') {

				obj.style.opacity = c;
				obj.style.filter = "alpha(opacity=" + (json[c] * 100) + ")";
			} else {

				obj.style[c] = json[c];
			}
		}

		return this;
	},

	anime: function (obj, attr, endTime, callback) {

		(obj.timer) && cancelAnimationFrame(obj.timer);

		var cssJosn = obj.currentStyle || getComputedStyle(obj, null),
			start = {},
			end = {},
			goTime;

		//设置初始属性值和结束属性值
		for (var key in attr) {

			if (attr[key] != parseFloat(cssJosn[key])) {

				start[key] = parseFloat(cssJosn[key]);
				end[key] = attr[key] - start[key];
			}
		}

		goTime = new Date();

		if (endTime instanceof Array) {

			(function delayFn() {

				if ((new Date() - goTime) >= endTime[0]) {

					endTime = endTime[1];
					goTime = new Date();
					ref();
				} else {

					obj.timer = requestAnimationFrame(delayFn);
				}
			})();
		} else {

			ref();
		}


		function ref() {

			var prop = (new Date() - goTime) / endTime;
			(prop >= 1) ? prop = 1: obj.timer = requestAnimationFrame(ref);
			for (var key in start) {

				var val = -end[key] * prop * (prop - 2) + start[key];

				if (key == 'opacity') {

					obj.style.opacity = val;
					obj.style.filter = "alpha(opacity=" + (val * 100) + ")";
				} else {

					obj.style[key] = val + 'px';
				}
			}

			(prop === 1) && callback && callback.call(obj);
		};
	}
}